package fiuba.algo3.modelo.mapa;

import java.util.Iterator;

import fiuba.algo3.modelo.Direccion;
import fiuba.algo3.modelo.Posicion;
import fiuba.algo3.modelo.factorVial.*;

public class GeneradorDeMapas {

	public Mapa crearMapaVacioDeDimensiones(int ancho, int alto){
		return (new Mapa(ancho,alto));
	}
	
	// MiniMapa usado hardcodeado para algunos tests
	public Mapa crearMiniMapaDePrueba(){
		Mapa mapa = this.crearMapaVacioDeDimensiones(3, 2);
		Cruce cruce = mapa.getCruceEn(new Posicion(0,0));
		cruce.getCalleHacia(Direccion.DERECHA).setObstaculo(new Pozo());
		cruce.getCalleHacia(Direccion.ABAJO).setSorpresa(new SorpresaCambio());
		cruce = mapa.getCruceEn(new Posicion(1,1));
		cruce.getCalleHacia(Direccion.DERECHA).setObstaculo(new Piquete());
		cruce.getCalleHacia(Direccion.ARRIBA).setSorpresa(new SorpresaDesfavorable());
		cruce = mapa.getCruceEn(new Posicion(1,0));
		cruce.getCalleHacia(Direccion.DERECHA).setObstaculo(new ControlPolicial());
		cruce.getCalleHacia(Direccion.DERECHA).setSorpresa(new SorpresaFavorable());
		return mapa;
	}
	

	public Mapa crearMapaVacioDeDimensionesAleatorias(){
		int ancho = this.enteroChicoAleatorio();
		int alto = this.enteroChicoAleatorio();
		return (this.crearMapaVacioDeDimensiones(ancho, alto));
	}
	
	public Mapa crearMapaAleatorio(){
		int ancho = this.enteroChicoAleatorio();
		int alto = this.enteroChicoAleatorio();
		return this.crearMapaAleatorioDeDimensiones(ancho, alto);
	}
	
	public Mapa crearMapaAleatorioDeDimensiones(int ancho, int alto){
		Mapa mapa = this.crearMapaVacioDeDimensiones(ancho, alto);
		IteradorDeMapa iterador = new IteradorDeMapa(mapa);
		while (iterador.hasNext()){
			Cruce cruce = iterador.next();
			Direccion[] direcciones = {Direccion.DERECHA, Direccion.ABAJO};
			for (Direccion direccion : direcciones)
				if (cruce.puedoIrHacia(direccion)){
					Calle calle = cruce.getCalleHacia(direccion);
					this.modificarCalleAleatoriamente(calle);
				}
		}
		return mapa;
	}
	
	public Mapa crearMapaPequenioFijo(){
		int ancho = 10;
		int alto = 10;
		Mapa mapa = this.crearMapaVacioDeDimensiones(ancho, alto);
		Iterator<Cruce> iterador = mapa.iterator();
		for (int i = 0, j = ancho*alto; iterador.hasNext(); i++, j--){
			Cruce cruce = iterador.next();
			switch (i%8){
				case 1: if (cruce.puedoIrHacia(Direccion.DERECHA))
							cruce.getCalleHacia(Direccion.DERECHA).setObstaculo(new Pozo());
						break;
				case 2: if (cruce.puedoIrHacia(Direccion.ABAJO))
							cruce.getCalleHacia(Direccion.ABAJO).setObstaculo(new Piquete());
						break;
				case 3: if (cruce.puedoIrHacia(Direccion.IZQUIERDA))
							cruce.getCalleHacia(Direccion.IZQUIERDA).setObstaculo(new ControlPolicial());
						break;
				default: break;
			}
			switch (j%8){
			case 1: if (cruce.puedoIrHacia(Direccion.DERECHA))
						cruce.getCalleHacia(Direccion.DERECHA).setSorpresa(new SorpresaFavorable());
					break;
			case 2: if (cruce.puedoIrHacia(Direccion.ABAJO))
						cruce.getCalleHacia(Direccion.ABAJO).setSorpresa(new SorpresaDesfavorable());
					break;
			case 3: if (cruce.puedoIrHacia(Direccion.ARRIBA))
						cruce.getCalleHacia(Direccion.ARRIBA).setSorpresa(new SorpresaCambio());
					break;
			default: break;
			}
		}
		
		return mapa;
	}
	
	
	
	
	
	private int enteroChicoAleatorio(){
		int entero = (int) Math.round(Math.random()*30);
		return entero;
	}

	private void modificarCalleAleatoriamente(Calle calle){
		double random = Math.random();
		if (random > 0.75){
			calle.setSorpresa(this.crearSorpresaAleatoria());
			calle.setObstaculo(this.crearObstaculoAleatorio());
		}
		else if (random > 0.5) calle.setSorpresa(this.crearSorpresaAleatoria());
		else if (random > 0.25)	calle.setObstaculo(this.crearObstaculoAleatorio());
	}

	private Sorpresa crearSorpresaAleatoria() {
		Sorpresa sorpresa;
		double random = Math.random();
			if (random < 0.33) sorpresa = new SorpresaFavorable();
			else if (random < 0.67) sorpresa = new SorpresaDesfavorable();
			else sorpresa = new SorpresaCambio();
		return sorpresa;
	}

	private Obstaculo crearObstaculoAleatorio() {
		Obstaculo obstaculo;
		double random = Math.random();
			if (random < 0.33) obstaculo = new Pozo();
			else if (random < 0.67) obstaculo = new Piquete();
			else obstaculo = new ControlPolicial();
		return obstaculo;
	}
}
